//若是小于10就加个0
function repair(i) {
  if (i >= 0 && i <= 9) {
    return "0" + i
  } else {
    return i
  }
}
import { fileAddress } from "@/libs/apiCommon"

import Plus from "@/assets/images/plus.png"
import Reduce from "@/assets/images/reduce.png"
import * as GC from "@grapecity-software/spread-sheets"

/**
 * 是否开启权限 （开发人员调试的时候，这个参数写false，不开启用户的菜单权限。）
 */
export const isOpenPermission = false
export class Utility {
  static setDict() {
    var dictData = {
      sex: [
        {
          value: 1,
          label: "男",
        },
        {
          value: 0,
          label: "女",
        },
      ],
      group: [
        {
          value: 1,
          label: "分组1",
        },
        {
          value: 2,
          label: "分组1",
        },
      ],
      version: [
        {
          value: 1,
          label: "版本1",
        },
        {
          value: 2,
          label: "版本2",
        },
      ],
      status: [
        {
          value: "1",
          label: "发布中",
        },
        {
          value: "2",
          label: "已发布",
        },
        {
          value: "3",
          label: "待发布",
        },
      ],
      folderType: [
        {
          value: 1,
          label: "国标",
        },
        {
          value: 2,
          label: "编码12",
        },
        {
          value: 3,
          label: "编码14",
        },
      ],
    }
    window.sessionStorage.setItem("dict", JSON.stringify(dictData))
  }

  static createTreeData(newData, allData) {
    newData.map((item) => {
      let single = {
        id: item.node.Id,
        label: item.node.FolderName,
        children: [],
      }
      if (item.childs != null && item.childs.length > 0) {
        single.children = []
        Utility.createTreeData(item.childs, single.children)
      } else {
        delete single.children
      }
      allData.push(single)
    })
  }

  static createTreeTableData(newData, allData) {
    newData.map((item) => {
      var name = ""
      if (item.node.FolderType == "1") {
        name = "编码附录A"
      }
      if (item.node.FolderType == "2") {
        name = "表12"
      }
      if (item.node.FolderType == "3") {
        name = "表14"
      }
      let single = {
        Id: item.node.Id,
        FolderName: item.node.FolderName,
        label: item.node.FolderName,
        EnCode: item.node.EnCode,
        FolderType: item.node.FolderType,
        FolderTypeName: name,
        FatherFolderId: item.node.FatherFolderId
          ? item.node.FatherFolderId
          : item.node.LastFolderId,
        children: [],
      }
      if (item.childs != null && item.childs.length > 0) {
        single.children = []
        Utility.createTreeTableData(item.childs, single.children)
      } else {
        delete single.children
      }
      allData.push(single)
    })
  }

  /**
   * 根据对象的某个属性值删除数组中的对象
   * @param {*} array 数组
   * @param {*} attr 字段
   * @param {*} value  字段值
   */
  static removeByAttr = (array, attr, value) => {
    for (var i = 0; i < array.length; i++) {
      if (array[i][attr] === value) {
        array.splice(i, 1)
        break
      }
    }
  }
  /**
   * 上传时文件的大小
   * @returns
   */
  static getLimitSize = () => {
    return 100
  }

  /** 获取当前周期 */
  static getCurrentPeriod = () => {
    const periodList = window.sessionStorage.getItem("periodList")
    return JSON.parse(periodList)
  }

  /**
   * 获取图片地址
   * @param {*} fileName
   * @returns
   */
  static getImgUrl = (fileName) => {
    return `${fileAddress}/ccdc/sys/common/static/${fileName}`
  }

  /**
   * 获取图片地址
   * @param {*} fileName
   * @returns
   */
  static getTitle = (type, name, select) => {
    let info = select.randomNo
      ? "]入组顺序号[" + select.groupSeq + "]" + "随机号[" + select.randomNo
      : "]筛选号[" + select.filterNo
    return (
      type +
      name +
      "【代码[" +
      select.examineeCode +
      "]名称[" +
      select.examineeName +
      info +
      "]】"
    )
  }

  /** 根据字典code获取字典list */
  static getDictList = (code) => {
    this.setDict()
    let dictData = window.sessionStorage.getItem("dict")
    if (dictData) {
      dictData = JSON.parse(dictData)
    }
    // 样品类型 sample_type
    // 样品状况 sample_status
    // 样品使用类型 sample_use_type
    // 状态 status
    // 冰箱类型 frig_type
    // 护理类型 nursing_type
    // 异常情况 abnormal_circumstance
    // 开关 is_open
    // 生活护理类型 life_care_type
    // 民族 nation
    // 检查项 Inspection_items
    // 采样类型  collect_type
    // 给药条件 drug_condition
    // 用餐类型 meal_type
    // 用餐类别/ 进餐类型 dining_type
    // 食谱类型 combo_type
    // 采集手指 collect_fingers
    // 采集类型 collect_type
    // 设备类型、设备型号 device_type
    // 试验类型 exp_type
    // 盲法 blind_method
    // 差异配置 diff_cfg
    // 给药途径 drug_way
    // 分组类型 group_type
    // 套餐类型 combo_type
    // 入组状态 group_in_status
    // 项目状态 project_status
    // 研究者类别 researcher_cate
    // 药品类型 drug_type
    // 剂型 drug_form
    // 受试者状态 e_status
    // 宣教状态 xj_status
    // 阶段 stage
    // 同步工作流引擎 activiti_sync
    // 权限策略 perms_type
    // 推送类别 msg_type
    // 删除状态 del_flag
    // 性别 sex
    // 全局权限策略 global_perms_type
    // 优先级 priority
    // 条件规则 rule_conditions
    // 状态 status
    // 操作类型 operate_type
    // 发布状态 send_status
    // 1是0否 yn
    return dictData[code]
  }

  /**
   * 获取当前日期时间
   * @returns 格式为：yyyy-mm-dd hh:mm:ss
   */
  static getCurrentTime = () => {
    var date = new Date() //当前时间
    var year = date.getFullYear() //年
    var month = repair(date.getMonth() + 1) //月
    var day = repair(date.getDate()) //日
    var hour = repair(date.getHours()) //时
    var minute = repair(date.getMinutes()) //分
    var second = repair(date.getSeconds()) //秒
    //当前时间
    var curTime =
      year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second
    return curTime
  }
  /**
   * 获取当前日期时间
   * @returns 格式为：yyyy-mm-dd hh:mm:ss
   */
  static getCurrentTimeHasChinese = () => {
    var date = new Date() //当前时间
    var year = date.getFullYear() //年
    var month = date.getMonth() + 1 //月
    var day = date.getDate() //日
    var hour = repair(date.getHours()) //时
    var minute = repair(date.getMinutes()) //分
    var second = repair(date.getSeconds()) //秒
    //当前时间
    var curTime =
      year +
      "年" +
      month +
      "月" +
      day +
      "日 " +
      hour +
      ":" +
      minute +
      ":" +
      second
    return curTime
  }
  /**
   * 获取当前日期时间
   * @returns 格式为：yyyy-mm-dd hh:mm:ss
   */
  static getCurrentDate = () => {
    var date = new Date() //当前时间
    var year = date.getFullYear() //年
    var month = repair(date.getMonth() + 1) //月
    var day = repair(date.getDate()) //日
    //当前时间
    var curTime = year + "-" + month + "-" + day
    return curTime
  }

  /**
   * 去空格
   * @param str 字符串
   * @param isAll true为去掉所有空格，false为去掉前后空格，默认false
   * @returns
   */
  static trimEmpty = (str, isAll) => {
    if (isAll) {
      return str.replace(/\s+/g, "")
    } else {
      return str.replace(/(^\s*)|(\s*$)/g, "")
    }
  }

  /**
   * 产生一个随机数
   * @param minOrMax 随机数下限（或上限，仅传入一个值时）
   * @param max 随机数上限
   * @returns
   */
  static random = (minOrMax, max) => {
    const min = typeof max === "undefined" ? 0 : minOrMax
    const max1 = typeof max === "undefined" ? minOrMax : max
    return parseInt(Math.random() * (max1 - min + 1), 10) + min
  }

  /**
   * 判断传入的2个值得值是否相等，
   * @param obj1 任意值
   * @param obj2 任意值
   */
  static isEqual(obj1, obj2) {
    function isObject(obj) {
      return typeof obj === "object" && obj !== null
    }
    // 两个数据有任何一个不是对象或数组
    if (!isObject(obj1) || !isObject(obj2)) {
      // 值类型(注意：参与equal的一般不会是函数)
      return obj1 === obj2
    }
    // 如果传的两个参数都是同一个对象或数组
    if (obj1 === obj2) {
      return true
    }

    // 两个都是对象或数组，而且不相等
    // 1.先比较obj1和obj2的key的个数，是否一样
    const obj1Keys = Object.keys(obj1)
    const obj2Keys = Object.keys(obj2)
    if (obj1Keys.length !== obj2Keys.length) {
      return false
    }

    //数组长度为0的特殊请框
    if (Array.isArray(obj1) && Array.isArray(obj2)) {
      if (obj1.length === 0 && obj2.length === 0) {
        return true
      }
    }
    // 如果key的个数相等,就是第二步
    // 2.以obj1为基准，和obj2依次递归比较
    for (let key in obj1) {
      // 比较当前key的value  --- 递归
      const res = Utility.isEqual(obj1[key], obj2[key])
      if (!res) {
        return false
      }
    }
    // 3.全相等
    return true
  }

  /**
   * 拉平对象数组  使用：Utility.arrayFlat(newTreeData, (t) => t.children)
   * @param source
   * @param childrenSelecter children 选择器
   * @param callback 回调 data=当前数据 level:递归层级
   */
  static arrayFlat = (source, childrenSelecter, callback) => {
    const list = []
    source.forEach((m) => {
      const children = this.getArrayList(m, childrenSelecter, callback, 1)
      callback && callback(m, 0, children)
      list.push(...children)
    })
    return list
  }

  /**
   * 折叠数组对象  使用： Utility.arrayCascade(newList,(c, p) => c.parentId == p.id,"children");
   * @param source
   * @param isChild 判断 child 是否是 parent 的子级
   * @param childrenFieldName children 字段名称，默认为 "children"
   */
  static arrayCascade = (source, isChild, childrenFieldName) => {
    for (let item of source) {
      item[childrenFieldName] = this.getChildren(item, source, isChild)
    }
    const result = []
    source.forEach((m) => {
      if (!m.$$hasParent) {
        result.push(m)
      }
      delete m["$$hasParent"]
    })
    return result
  }

  static getChildren = (item, source, isChild) => {
    const result = []
    source.forEach((m) => {
      const r = isChild(m, item)
      if (!m.$$hasParent) {
        m.$$hasParent = r
      }
      if (r) {
        result.push(m)
      }
    })
    return result
  }

  static getArrayList = (item, childrenSelecter, callback, level) => {
    const list = [item]
    const c = childrenSelecter(item)
    c &&
      c.forEach((m) => {
        m.level = level + 1
        const children = this.getArrayList(
          m,
          childrenSelecter,
          callback,
          level + 1
        )
        callback && callback(m, level, children)
        list.push(...children)
      })
    return list
  }

  static _debounce = []

  /**
   * 延迟调用指定的方法(防抖动)
   * @param func
   * @param delay
   */
  static debounce = (func, delay = 500) => {
    if (delay < 0) {
      delay = 10
    }
    var hash = func.toString()
    var find = null
    for (var i = 0; i < this._debounce.length; i++) {
      if (this._debounce[i].funcId === hash) {
        find = this._debounce[i]
        break
      }
    }
    if (find === null) {
      find = {}
      this._debounce.push(find)
    } else {
      clearTimeout(find.taskId)
    }
    find.funcId = hash
    find.taskId = setTimeout(func, delay)
  }

  // base64转blob
  static base64ToBlob = (dataURI) => {
    var mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0] // mime类型
    var byteString = atob(dataURI.split(",")[1]) //base64 解码
    var arrayBuffer = new ArrayBuffer(byteString.length) //创建缓冲数组
    var intArray = new Uint8Array(arrayBuffer) //创建视图

    for (var i = 0; i < byteString.length; i++) {
      intArray[i] = byteString.charCodeAt(i)
    }
    return new Blob([intArray], { type: mimeString })
  }

  static xhrRequest = (file) => {
    return new Promise((resolve) => {
      const xhr = new XMLHttpRequest()
      const fd = new FormData()
      fd.append("file", file)
      xhr.onload = () => {
        if (xhr.readyState === 4 && xhr.status === 200) {
          resolve(JSON.parse(xhr.responseText))
        }
      }
      xhr.open("post", `/ccdc/sys/common/upload`, true)

      let projectTestperiod = window.sessionStorage.getItem("projectTestperiod")
      if (projectTestperiod) {
        projectTestperiod = JSON.parse(projectTestperiod)
      }
      xhr.setRequestHeader("X-Access-Token", localStorage.getItem("token"))
      xhr.setRequestHeader("pmId", projectTestperiod.projectId)
      xhr.setRequestHeader("expId", projectTestperiod.testId)
      xhr.setRequestHeader("periodNo", projectTestperiod.periodId)
      xhr.send(fd)
    })
  }

  /**
   * dom全屏
   * @param ele
   */
  static domFullScreen = (ele) => {
    //Chrome等
    if (ele.requestFullscreen) {
      ele.requestFullscreen()
    } else if (ele.mozRequestFullScreen) {
      ele.mozRequestFullScreen()
    } else if (ele.webkitRequestFullscreen) {
      ele.webkitRequestFullscreen()
    } else if (ele.msRequestFullscreen) {
      ele.msRequestFullscreen()
    }
  }

  /**
   * dom退出全屏
   */
  static docExitFullScreen = () => {
    if (document.exitFullScreen) {
      document.exitFullScreen()
    } else if (document.mozCancelFullScreen) {
      document.mozCancelFullScreen()
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen()
    } else if (document.msExitFullscreen) {
      document.msExitFullscreen()
    }
  }
}

export class SpreadCommon {
  /** 重新缩放页面，避免spreadjs表格缩成一团 */
  static setResize = () => {
    var myEvent = new Event("resize")
    window.dispatchEvent(myEvent)
  }

  /**
   * 设置sheet的高度
   * @param sheet 当前激活的sheet
   * @param colHeaderRowHeight 列头的行高
   * @param rowHeight 内容的行高
   */
  static setSheetHeight = (sheet, colHeaderRowHeight = 35, rowHeight = 28) => {
    sheet.defaults.rowHeight = rowHeight // 内容的行高
    sheet.defaults.colHeaderRowHeight = colHeaderRowHeight // 列头的行高
  }

  /**
   * 设置sheet内容第一列的层级，形成
   * @param sheet
   * @param showCheckBox 是否显示checkbox
   */
  static initOutlineColumn = (sheet, showCheckBox = true) => {
    sheet.outlineColumn.options({
      columnIndex: 0, // 这里默认第一列有层级
      showCheckBox: showCheckBox, // 是否显示checkbox
      expandIndicator: Plus,
      collapseIndicator: Reduce,
    })
    sheet.showRowOutline(false) // 去掉excel里面的group分组
    sheet.outlineColumn.refresh()
  }

  /**
   * 设置通用的颜色
   * @param sheet
   */
  static setCommonColor = (sheet) => {
    let spreadNS = GC.Spread.Sheets
    //#region 全局表头颜色样式
    let headerStyle = new spreadNS.Style()
    headerStyle.vAlign = GC.Spread.Sheets.VerticalAlign.center // 文字垂直居中
    headerStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.center // 文字横向居左
    headerStyle.textIndent = 1
    headerStyle.font = "11pt Arial"
    headerStyle.backColor = "#f9f9f9"
    headerStyle.borderLeft = new GC.Spread.Sheets.LineBorder(
      "#e0e0e0",
      GC.Spread.Sheets.LineStyle.thin
    )
    headerStyle.borderTop = new GC.Spread.Sheets.LineBorder(
      "#e0e0e0",
      GC.Spread.Sheets.LineStyle.thin
    )
    headerStyle.borderRight = new GC.Spread.Sheets.LineBorder(
      "#e0e0e0",
      GC.Spread.Sheets.LineStyle.thin
    )
    headerStyle.borderBottom = new GC.Spread.Sheets.LineBorder(
      "#e0e0e0",
      GC.Spread.Sheets.LineStyle.thin
    )
    sheet.setStyle(-1, -1, headerStyle, spreadNS.SheetArea.colHeader)
    //#endregion

    //#region 全局内容颜色样式
    let contentStyle = new spreadNS.Style()
    contentStyle.vAlign = GC.Spread.Sheets.VerticalAlign.center
    contentStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.left
    contentStyle.textIndent = 1
    contentStyle.backColor = "#ffffff"
    contentStyle.font = "10pt Arial"
    // 自动换行
    // contentStyle.wordWrap = true
    // 超过打点，鼠标经过会显示完整的文字
    contentStyle.showEllipsis = true

    sheet.setStyle(-1, -1, contentStyle, spreadNS.SheetArea.viewport)
    //#endregion

    //边框
    sheet
      .getRange(-1, -1, -1, -1, GC.Spread.Sheets.SheetArea.viewport)
      .setBorder(
        new GC.Spread.Sheets.LineBorder(
          "#e0e0e0",
          GC.Spread.Sheets.LineStyle.thin
        ),
        { all: true },
        1
      )
    sheet
      .getRange(-1, -1, -1, -1, GC.Spread.Sheets.SheetArea.rowHeader)
      .setBorder(
        new GC.Spread.Sheets.LineBorder(
          "#e0e0e0",
          GC.Spread.Sheets.LineStyle.thin
        ),
        { all: true },
        1
      )
  }

  // 所有单元格不可编辑
  static setAllNoEdit = (sheet) => {
    let spreadNS = GC.Spread.Sheets
    let notEditStyle = new spreadNS.Style()
    notEditStyle.backColor = "#EFF3F8"
    notEditStyle.font = "10pt Arial"
    notEditStyle.textIndent = 1
    notEditStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.left
    notEditStyle.vAlign = GC.Spread.Sheets.VerticalAlign.center
    sheet.setStyle(-1, -1, notEditStyle, spreadNS.SheetArea.viewport)
  }
}
